package com.example.demo.shiro;

import com.example.demo.jwt.JwtUtils;
import io.jsonwebtoken.Claims;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class ConsumeFilter extends AccessControlFilter {
    @Bean
    public JwtUtils jwtUtils(){
        return  new JwtUtils();
    }
    @Bean("urlPermissionResolver")
    public UrlPermissionResolver urlPermissionResolver(){
        return  new UrlPermissionResolver();
    }
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        return super.preHandle(request, response);
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        //return false  直接走onAccessDenied方法
        return false;
    }


    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        //return true 响应请求的url  return false 不处理请求

        System.out.println("i am onAccessDenied");
        String token = ((HttpServletRequest) request).getHeader("token");
        Claims claims=jwtUtils().getClaimByToken(token);
        if(claims==null||JwtUtils.isTokenExpired(claims.getExpiration())){
            throw new Exception("token过期 失效 请重新登陆");
        }

        if(StringUtils.isEmpty(token)){
            //1.请求头中没有token，非法请求,跳转去登陆url
            throw new Exception("token  is null 跳转去登陆url");

        }
        System.out.println("token is :"+token);
        //拿到传过来的token 转换成AuthenticationToken类型
        ConsumeToken  consumeToken=new ConsumeToken(token);
        Subject subject = getSubject(request,response);
        String url = getPathWithinApplication(request);
        if(StringUtils.isEmpty(url)){
            return  false;
        }
        int index=url.lastIndexOf("/");//类似这样的url  /User/delete
        try {
            subject.login(consumeToken);
            //截取后delete跟数据库中的delete进行比较 return true说明有该权限
            boolean permitted = subject.isPermitted(url.substring(index+1));
            System.out.println("permitted url:"+permitted);
            if (permitted){
                return  true;
            }else{
                throw new Exception("token  没有该授权");
            }

        } catch (AuthenticationException e) {
//            e.printStackTrace();
            //2.有token 但是token过期或者不匹配
            throw new Exception("token 认证失败");
        }
    }
}
